﻿using com.kmer.Hook;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace com.kmer {
	public sealed class HookService {
		private HookService() {
			var assemblys = AppDomain.CurrentDomain.GetAssemblies().Where(item => item.GlobalAssemblyCache == false);
			foreach (var k in assemblys) {
				FindAndRegister(k);
			}
		}
		void FindAndRegister(System.Reflection.Assembly assembly) {
			var type = typeof(BaseHook);
			try {
				var modules = assembly.GetTypes().Where(item => item.BaseType == type || item.IsSubclassOf(type));
				foreach (var k in modules) {
					Register(k);
				}
			} catch (ReflectionTypeLoadException ex) {
				Log.Error("加载Type错误：{0}\n详细信息：{1}", "ReflectionTypeLoadException", ex.Message, ex.ToString());
			} catch (Exception ex) {
				Log.Error("注册错误：{0}\n详细信息：{1}", "Exception", ex.Message, ex.ToString());
			}
		}
		void Register(Type pHander) {
			var t = pHander;
			while (t != null && t.BaseType != typeof(BaseHook)) {
				t = t.BaseType;
			}
			if (t == null) return;
			if (_hooks == null) _hooks = new Dictionary<int, IList<IHook>>();
			var inc = Activator.CreateInstance(pHander) as BaseHook;
			if (inc == null) return;
			var list = _hooks.Where(item => item.Key == inc.HookType).Select(item => item.Value).FirstOrDefault() ??
					   new List<IHook>();
			list.Add(inc);
			_hooks[inc.HookType] = list.OrderByDescending(item => item.Priority).ToList();
		}

		static HookService _instance;
		public static HookService Instance {
			get { return _instance ?? (_instance = new HookService()); }
		}

		Dictionary<int, IList<IHook>> _hooks;

		public void Invoke(HookTypes pHookEvent, params object[] pArgs) {
			Invoke((int)pHookEvent, pArgs);
		}

		public void Invoke(int pHookEvent, params object[] pArgs) {
			if (!_hooks.ContainsKey(pHookEvent)) return;
			var list = _hooks[pHookEvent];
			var qs = list.OrderByDescending(item => item.Priority);
			foreach (var k in qs) {
				bool isEnd;
				var r = k.Execute(out isEnd, pArgs);
				Log.WriteLog("执行：{0} 结果： {1}", "HOOK Execute", Log.LogType.INFO, k, r);
				if (isEnd) break;
			}
		}
	}
}
